var GlobalContainer = new Array();
  
function UserControlGroup(name,width,height)
{
    this.name = name;
    this.logger = new Logger(name);
    this.logger.log('ctor','creating new ucg grid (RxC) '+height+'x'+width);
    this.focusStack = new Array();
    this.objects = new Array();
    this.objects.length = width;
    for (i = 0 ; i < height; ++i)
    {
        this.objects[i] = new Array();
        this.objects[i].length = width;
    }
    this.width = width;
    this.height = height;
    this.activeRow = 0;
    this.activeCol = 0;
    this.wrap = true;
    this.useFocus = false;
    this.focusUsed = false;
    this.tmpObjRow = 0;
    this.tmpObjCol = 0;
    this.curObj = null;
    this.special = new Array();
    this.container = GlobalContainer;
}

UserControlGroup.prototype = new UserControl();

UserControlGroup.prototype._getObject = function(obj)
{
    for (var i = 0 ; i < this.objects.length ; ++i)
        for (var j = 0 ; j < this.objects[i].length ; ++j)
            if (this.objects[i][j] == obj)
            {
                this.tmpObjRow = i;
                this.tmpObjCol = j;
                return true;
            }
    this.tmpObjRow = -1;
    this.tmpObjCol = -1;
    return false;
}
UserControlGroup.prototype._setTempAsActive = function()
{
     this.activeRow = this.tmpObjRow;
     this.activeCol = this.tmpObjCol;
     this.curObj = this.objects[this.activeRow][this.activeCol];
}


UserControlGroup.prototype.wrapFocus = function(bool)
{
    this.wrap = bool;
}
UserControlGroup.prototype.activate = function(obj)
{
    if (this._getObject(obj))
    {
        if (this.active)
        {
            if (this.curObj != null && this.curObj != obj)
                if (this.curObj.deactivate())
                {
                    this._setTempAsActive();
                    this.curObj.activate();
                }
        }
        else
        {
            this._setTempAsActive();
        }
    }
    else
        alert('Cant find object to activate');
}   


UserControlGroup.prototype.activate = function()
{
    this.logger.log('activate',this);
    if (this.active)
        return;
    this.active = true;
    if (this.curObj != null && this.useFocus == false)
        this.curObj.activate();
}


UserControlGroup.prototype.deactivate = function(obj)
{
    this.logger.log('deactivate child',obj);
    if (this.active)
    {
        if (this.useFocus)
            if (this.curObj != null)
                this.curObj.deactivate();
        else
        {
            alert('Cant deactivate object. Container cant take focus!');
            return false;
        }
    }
    return true;
}

UserControlGroup.prototype.deactivate = function()
{
    this.logger.log('deactivate',this);
    if (this.active)
    {
        if (this.curObj.deactivate())
        {
            this.active = false;
            return true;
        }
        return false;
    }
    return true;
}

UserControlGroup.prototype.forceFocus = function(obj)
{
    if (this.active)
    {
        if (this.curObj != null && obj != this.curObj)
            if (this.curObj.deactivate())
            {
                this.curObj = obj;
                if (this._getObject(obj))
                   this._setTempAsActive();
                else
                    return false;
                return true;
            }
            return false;
    }
    else
    {
        this.container.forceFocus(this);
        if (this.active)
            this.curObject.activate();
        return true;
    }
}

UserControlGroup.prototype.registerObject = function(object,row,col)
{
    this.logger.log('registerObject',object);
    if (this.objects[row][col] != null)
        alert('Object already registered in [' + row +']['+col+']');
    this.objects[row][col] = object;
    object.container = this;
    if (row == 0 && col == 0)
        this.curObj = object;
}


UserControlGroup.prototype.registerKey = function(keyCode,func)
{
    var tmp = this.special[keyCode];
    this.special[keyCode] = func;
    return tmp;
    
}

UserControlGroup.prototype.unregisterKey = function(keyCode,func)
{
    var tmp = this.special[keyCode];
    delete this.special[keyCode];
    return tmp;    
}


UserControlGroup.prototype.handleInput = function(key)
{
    this.logger.log('handleInput',key);
    var hiResult = false;
    
    if (this.special[key] != undefined)
    {   
        this.special[key]();
        return false;
    }
        
    if (this.curObj != null && this.curObj.active)
    {
        this.logger.log('handleInput','child is active. Calling curObj.handleInput');
        hiResult = this.curObj.handleInput(key);
        
        if (hiResult === false)
            return false;
        this.logger.log('handleInput','child command: '+ hiResult.command);
        this.logger.log('handleInput','child order: '+ hiResult.order);
        if (hiResult.command == $.sfKey.ENTER)
        {
            this.logger.log('handleInput','pushing child onto focus stack');
            this.focusStack.push(this.curObj);
        }
        key = hiResult.order;
    }
    switch (key)
    {
        case $.sfKey.LEFT:
            this.activeCol--;
            if (this.activeCol < 0)
                if (this.wrap)
                    this.activeCol = this.width-1;
                else
                    this.activeCol = 0;
            break;
        case $.sfKey.RIGHT:
            this.activeCol++;
            this.logger.log('handleInput', 'setting col ' + this.activeCol +' of ' + this.width);
            if (this.activeCol >= this.width)
                if (this.wrap)
                    this.activeCol = 0;
                else
                    this.activeCol = this.width-1;
            break;
        case $.sfKey.UP:
             this.activeRow--;
            if (this.activeRow < 0)
                if (this.wrap)
                    this.activeRow = this.height-1;
                else
                    this.activeRow = 0;
            break;
        case $.sfKey.DOWN:
            this.activeRow++;
            this.logger.log('handleInput', 'setting row ' + this.activeRow  +' of ' + this.height);
            if (this.activeRow >= this.height)
                if (this.wrap)
                    this.activeRow = 0;
                else
                    this.activeRow = this.height-1;
            break;
        case $.sfKey.ENTER:
            if (this.curObj != null)
                this.focusStack.push(this.curObj);
            break;
        case $.sfKey.RETURN:
            if (this.focusStack.length == 0 && this.useFocus == false)
            {
                this.logger.log('handleInput','stack empty, returning focus');
                var res = {order : $.sfKey.RETURN};
                return res;
            }
            this.logger.log('handleInput','poping child from focus stack');
            var prev = this.focusStack.pop();
            
            this._getObject(prev);
            this.curObj.deactivate();
            this._setTempAsActive();
            this.curObj.activate();
            return false;
        default:
            return false;
    }
    this.logger.log('handleInput','activateing [' + this.activeRow + '][' + this.activeCol +']');
    if (this.curObj != null)
        this.curObj.deactivate();
    this.curObj = this.objects[this.activeRow][this.activeCol];
    if (this.curObj != null)
        this.curObj.activate();
    else
        this.logger.log('handleInput','Cant activate - curObj is null');
    return false;
}


CodeRepo.SetReady('UserControlGroup');